﻿// RankingSejmowy 1.0 - Polish parliment statistics for the masses.
// Copyright (C) 2010 Jarosław Dubrownik
//  
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//  
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//  
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using RankingSejmowy.Common.Exceptions;
using RankingSejmowy.Common.Extensions;
using RankingSejmowy.Model;
using RankingSejmowy.Model.Import;

namespace RankingSejmowy.BLL.Import.Parser.PageParsers
{
    internal class PartyVotingParser : IPartyVotingParser
    {
        private const string PARTY_VOTING_TITLE_PATTERN =
            @"G.osowanie.+?>(?'voting'\d+).+?(?'date'\d{2}-\d{2}-\d{4}).+?Wyniki.+?>(?'party'.+?)<";

        private const string DEPUTY_VOTING_PATTERN = @"<TD>(?'name'.+?)<.+?<TD>.+?>(?'vote'.+?)<";

        #region IPartyVotingParser Members

        public void Parse(IEnumerable<SiteMapPage> partyVotingPages, Voting voting)
        {
            foreach (var partyVotingPage in partyVotingPages)
            {
                ParsePartVoting(partyVotingPage, voting);
            }
        }

        #endregion

        private void ParsePartVoting(SiteMapPage partyVotingPage, Voting voting)
        {
            var content = partyVotingPage.DownloadedPage.GetContent();
            try
            {
                var party = ParsePartyVotingTitle(voting, content);
                ParseDeputyVotings(voting, party, content);
            }
            catch (ParseException e)
            {
                throw new ParseException(string.Format("party voting page ({0})", partyVotingPage.Uri), e);
            }
        }

        private Party ParsePartyVotingTitle(Voting voting, string content)
        {
            var match = content.Match(PARTY_VOTING_TITLE_PATTERN, RegexOptions.Singleline);
            if (!match.Success)
            {
                throw new ParseException("party voting title");
            }

            var cadence = voting.Meeting.Cadence;
            var date = match.Groups["date"].Value.ConvertToDateTime("dd-MM-yyyy");
            var partyName = match.Groups["party"].Value;
            return cadence.GetParty(partyName) ?? cadence.NewParty(partyName, date);
        }

        private void ParseDeputyVotings(Voting voting, Party party, string content)
        {
            var matches = content.Matches(DEPUTY_VOTING_PATTERN, RegexOptions.Singleline);
            var cadence = voting.Meeting.Cadence;
            var partyCadence = cadence.GetPartyCadence(party, cadence);
            foreach (Match match in matches)
            {
                ParseDeputyVote(match, partyCadence, voting);
            }
        }

        private void ParseDeputyVote(Match match, PartyCadence partyCadence, Voting voting)
        {
            throw new NotImplementedException();
            //var vote = EVoteHelper.Parse(match.Groups["vote"].Value);
            //var nameTokens = match.Groups["name"].Value.Split(' ');
            //var lastName = nameTokens[0];
            //var middleName = string.Empty;
            //var firstName = string.Empty;
            //if (nameTokens.Length == 3)
            //{
            //    middleName = nameTokens[1];
            //    firstName = nameTokens[2];
            //}
            //else
            //{
            //    firstName = nameTokens[1];
            //}

            //var deputy = partyCadence.GetDeputy(lastName, firstName) ??
            //             partyCadence.NewDeputy(firstName, middleName, lastName);
            //var deputyVote = new DeputyVote
            //                     {
            //                         Voting = voting,
            //                         Vote = vote
            //                     };
            //deputy.AddDeputyVote(
            //    deputyVote, partyCadence);
            //voting.AddDeputyVote(deputyVote);
        }
    }
}